home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
026-050
/
scopedisk27
/
hopalong
/
hop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-18
|
6KB
|
220 lines
/*
First Wave program Ranjit Bhatnagar
ranjit@eniac.seas.upenn.edu
All this code is public domain - as if anyone would want
to steal it. I would love to see improved versions -
a nicer interface, a fixed-point implementation for speed.
30 Aug '88
Shell of First Wave has been
modified to be a quick Hopalong - as described in Dewdney's
Mathematical Games column, "Scientific American" Sept 86 -
and invented by Barry Martin.
Basically, it's an iterated function:
x = 0
y = 0
for i = 1 to num
plot (x, y)
xx = y - sign(x)*sqrt[abs(b*x-c)]
yy = a - x
x = xx
y = yy
where a, b, and c are constants entered by the user. (Some suggested
values: -1000, .1, -10; -200, .1, -80; .4, 1, 0; -3.14, .3, .3)
A simpler function (not implemented here) is
x = y - sin(x)
y = a - x
Martin recommends values of a within .07 of pi for this one.
user must also specify the range of values that will be visible on
the screen. [INSTEAD I put in "magnification"]
Things to do:
allow specification of visible range.
Clever colors.
Fixed-point for speed.
the latest: changed to interlace, doubled pixel height, reduced
frequency of checks for close-box...
*/
/* create a nice screen */ /* Thanks Rob Peck and "Programmer's Guide" */
#include "hop.h"
struct TextAttr waveScrFont = { /* for basic methods in Intuition */
"topaz.font", 8, 0, 0
};
#define WID 640
#define HEI 400
struct NewScreen waveScr = {
0, 0, /* left and top edges */
WID, HEI, /* width and height */
4, /* bitplanes */
1, 0, /* detail and block pens */
LACE|HIRES, /* screen view type */
CUSTOMSCREEN, /* type */
&waveScrFont, /* font */
"Hopalong", /* title */
NULL, /* user gadgets */
NULL /* custom bitmap */
};
/* some pretty colors for it */
UWORD waveCols[] = {
0x0000, 0x0e30, 0x0fff, 0x0b40,
0x0b04, 0x05d0, 0x0ed0, 0x07df,
0x069f, 0x0c0e, 0x0f2e, 0x0feb,
0x0c96, 0x0bbb, 0x07df, 0x0bf0
};
/* and a nice window */
struct NewWindow waveWin = {
0, 15, /* left and top edges */
WID-1, HEI-16, /* size */
2, 3, /* detail and block pens */
CLOSEWINDOW, /* flags */
SIMPLE_REFRESH | WINDOWCLOSE | GIMMEZEROZERO,
NULL, NULL,
"Hopalong",
NULL, /* the screen */
NULL, /* the bitmap */
10, 10, -1, -1,
CUSTOMSCREEN
};
/* the precomputed tables */
/* uncomment these if you decide to put fixedpoint into the program... */
/* extern WORD sinetab[];*/ /* 257 sines from 0 to 2pi, all 16 bits are frac */
/* extern WORD sqrttab[];*/ /* 257 sqrts from 0 to 256, low 12 bits are frac */
/* extern double ran(); */
/* globals */
struct Screen *scr = 0;
struct Window *win = 0;
struct RastPort *rp = 0;
struct ViewPort *vp = 0;
int GfxBase = 0;
int IntuitionBase = 0;
/* Open libraries & such */
OpenThings()
{
GfxBase = OpenLibrary("graphics.library",0);
if (GfxBase == 0) Die("Couldn't open graphics.library");
diag("opened grafix");
IntuitionBase = OpenLibrary("intuition.library",0);
if (IntuitionBase == 0) Die("Couldn't open intuition.library");
diag("opened intuition");
scr = OpenScreen(&waveScr);
if (scr == 0) Die("Screen nailed shut");
diag("opened screen");
vp = &(scr->ViewPort);
waveWin.Screen = scr;
win = OpenWindow(&waveWin);
if (win == 0) Die("Window painted shut");
diag("opened window");
rp = win->RPort;
}
/* Fail */
Die(s)
char *s;
{
printf("%s\nSo much for this program.\n",s);
CloseThings();
}
/* Close libraries & such */
CloseThings()
{
diag("Closing everything up.");
if (win) CloseWindow(win);
if (scr) CloseScreen(scr);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
}
/* display a message */
diag(s)
char *s;
{
printf("%s\n",s);
}
/* THIS IS IT */
main()
{
struct IntuiMessage *msg;
int i, j; /* current pt */
int m,n; /* just keep track of how many pixels we've plotted */
float a, b, c, x, y, xx, yy;
int foo; /* sure wish C had a "sign" function and an "abs" */
float bar;
float mag;
OpenThings();
LoadRGB4(vp, waveCols, 16);
SetDrMd(rp, JAM1);
n = x = y = 0;
WBenchToFront();
printf("Please enter values for a, b, c, and magnification: ");
scanf("%e %e %e %e",&a,&b,&c,&mag);
c = sin((double)b); /* force math library to be loaded now */
WBenchToBack();
while (0 == (msg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
for (m=0; m<100; m++) { /* check for messages only every 100th */
SetAPen(rp, (++n >> 8) % 16);/* for now, color changes every 256 pts */
i = (int)(WID/2+mag*x) % 2000; /* 2000 picked out of a hat */
j = (int)(HEI/2+mag*y) % 2000;
WritePixel(rp, i, j);
WritePixel(rp, i, j+1); /* why? To reduce interlace flicker */
if (x<0) foo=-1; else foo=1;
if ((bar=b*x-c)<0) bar=-bar;
xx = y - foo*sqrt((double)bar);
yy = a - x;
x = xx;
y = yy;
}
}
do {
ReplyMsg(msg);
} while (msg = (struct IntuiMessage *)GetMsg(win->UserPort));
finish:
CloseThings();
}